<?php

namespace app\admin\service;

use app\admin\service\statistics\completions\CellCompletion;
use app\admin\service\statistics\completions\TimesCompletion;
use app\admin\service\statistics\filters\ChainFilter;
use app\admin\service\statistics\filters\GroupFilter;
use app\admin\service\statistics\filters\TimeFilter;
use app\admin\service\statistics\groupers\DateGrouper;
use app\admin\service\statistics\promotion\AbstractComputeStatistician;
use app\admin\service\statistics\promotion\AbstractQueryStatistician;
use app\admin\service\statistics\promotion\Provider;
use ShidianUtil\Utils\TimeUtil;

/**
 * 渠道数据统计表2
 * Class PromotionTable2Service
 * @package app\admin\service
 */
class PromotionTable2Service
{
    private array $provider = [];

    public function __construct(Provider $provider)
    {
        $this->provider = $provider->getProvider();
    }

    /**
     * 渠道分组对比数据统计
     * @param $groupId
     * @param array $fields
     * @param $startTime
     * @param $endTime
     * @return array
     */
    public function indexOfGroup2($groupId, array $fields, $startTime, $endTime)
    {

        $groupFilter = new GroupFilter([$groupId]);
        $timeFilter = new TimeFilter($startTime, $endTime);

        $cellCompletion = new CellCompletion($startTime);

        // 过滤
        $filters = [$timeFilter, $groupFilter];

        // 分组
        $groupers = [];

        // 补齐
        $completions = [$cellCompletion];

        $data = [];
        foreach ($fields as $field) {
            $data[] = $this->getData($field, $filters, $groupers, $completions)[0];
        }

        return $data;
    }

    /**
     * 渠道数据
     * @param $groupId
     * @param array $chains
     * @param string $field
     * @param $startTime
     * @param $endTime
     * @return array
     */
    public function indexOfGroupChains($groupId, array $chains, string $field, $startTime, $endTime)
    {

        $times = TimeUtil::timeList(TimeUtil::DAY, $startTime, $endTime, true);

        $groupFilter = new GroupFilter([$groupId]);
        $chainFilter = new ChainFilter($chains);
        $timeFilter = new TimeFilter($startTime, $endTime);

        $dateGrouper = new DateGrouper();

        $timesCompletion = new TimesCompletion($times);


        // 过滤
        $filters = [$groupFilter, $chainFilter, $timeFilter];

        // 分组
        $groupers = [$dateGrouper];

        // 补齐
        $completions = [$timesCompletion];

        return $this->getData($field, $filters, $groupers, $completions);
    }

    private function getData($field, $filters, $groupers, $completions): array
    {
        // 这里可以缓存，但是现在没必要

        $define = $this->provider[$field];

        $implClass = $define['implClass'];
        $statisticians = $define['statisticians'] ?? [];


        $impl = new $implClass();

        if ($impl instanceof AbstractQueryStatistician) {

            // 设置筛选
            if (!empty($filters)) {
                $impl->setFilters(...$filters);
            }

            // 设置分组统计
            if (!empty($groupers)) {
                $impl->setGroupers(...$groupers);
            }

            // 设置补齐
            if (!empty($completions)) {
                $impl->setCompletions(...$completions);
            }

        } elseif ($impl instanceof AbstractComputeStatistician) {

            // 设置补齐
            if (!empty($completions)) {
                $impl->setCompletions(...$completions);
            }

            // 获取依赖字段
            $statisticianMap = [];
            foreach ($statisticians as $statistician) {
                $statisticianMap[$statistician] = $this->getData($statistician, $filters, $groupers, $completions);
            }
            if (!empty($statisticianMap)) {
                $impl->setStatisticiansMap($statisticianMap);
            }
        }

        return $impl->getData();
    }

}
